package com.naiterui.ehp.bs.doctor.service.record.impl;

import static com.naiterui.ehp.bp.domain.Licence.DOCTOR_LICENCE_TYPE_IDCARD;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.naiterui.ehp.bp.bo.doctor.RecordParamAuditBO;
import com.naiterui.ehp.bp.domain.Doctor;
import com.naiterui.ehp.bp.domain.Hospital;
import com.naiterui.ehp.bp.domain.Licence;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.doctor.dao.user.ILicenceDao;
import com.naiterui.ehp.bs.doctor.domain.RecordUserInfo;
import com.naiterui.ehp.bs.doctor.exception.ExceptionCodes;
import com.naiterui.ehp.bs.doctor.repository.IDoctorRepository;
import com.naiterui.ehp.bs.doctor.repository.IHospitalRepository;
import com.naiterui.ehp.bs.doctor.repository.ILicenceRepository;
import com.naiterui.ehp.bs.doctor.service.IAuditService;
import com.naiterui.ehp.bs.doctor.utils.SealImageUtil;
import com.naiterui.ehp.bs.doctor.vo.record.RecordInfoVO;
import com.naiterui.ehp.bs.doctor.vo.record.ReocrdUserBaseInfoVO;

import cn.hutool.core.util.IdcardUtil;

/**
 * @author guoyongxiang
 * @date 2020/2/20 17:03
 * @since 1.0.0
 */
@Service
public class RecordInfoDoctorServiceImpl extends AbstractRecordInfoServiceImpl {

    private static final Logger LOGGER = LoggerFactory.getLogger(RecordInfoDoctorServiceImpl.class);

    @Autowired
    private IDoctorRepository doctorRepository;
    @Autowired
    private IHospitalRepository hospitalRepository;
    @Autowired
    private ILicenceRepository licenceRepository;
    @Autowired
    private IAuditService auditService;
    @Autowired
    private ILicenceDao licenceDao;

    @Value("${file.base.prefix}")
    private String fileBasePrefix;
    /**
     * 签名印章图片路径前缀
     */
    @Value("${file.base.prefix}/recommend/images/seal/")
    public String sealPathPre;

    public void updateCallbackAfter(RecordUserInfo userInfo) throws BusinessException {
        Long doctorId = userInfo.getUserId();
        if (RecordUserInfo.STATUS_PASS.equals(userInfo.getStatus())) {
            LOGGER.info("监管平台，医生备案成功 doctorId:{}", userInfo.getUserId());
            Doctor doctor = this.doctorRepository.get(doctorId);
            if (doctor == null) {
                LOGGER.warn("医生ID不存在 doctorId:{}", doctorId);
                throw new BusinessException(ExceptionCodes.USER_NOT_EXIST);
            }

            // 兼容已通过审核医生被挂起后，重新通过审核，不变更医生备案状态
            if (Doctor.AUTH_STATUS_SUCCESS == doctor.getStatus()) {
                return;
            }

            RecordParamAuditBO auditBO = new RecordParamAuditBO();
            auditBO.setStatus(Doctor.RECORD_STATUS_SUCCESS);
            auditBO.setDoctorId(doctorId);
            this.auditService.saveRecordInfo("海南监管备案平台", auditBO);
        } else if (RecordUserInfo.STATUS_HANG.equals(userInfo.getStatus())) {
            LOGGER.info("监管平台，医生备案挂起 doctorId:{}, recordStatus:{}", userInfo.getUserId(), userInfo.getStatus());
        } else {
            LOGGER.info("监管平台，医生备案失败 doctorId:{}, recordStatus:{}", userInfo.getUserId(), userInfo.getStatus());
        }
    }

    /**
     * 更新基础信息
     *
     * @param baseInfoVO
     * @param operator
     *
     * @return
     *
     * @throws BusinessException
     */
    @Override
    protected String updateBaseInfo(RecordInfoVO recordInfoVO, String operator) throws BusinessException {
        ReocrdUserBaseInfoVO baseInfoVO = recordInfoVO.getUserBaseInfo();
        Doctor doctor = this.doctorRepository.get(baseInfoVO.getUserId());
        if (doctor == null) {
            LOGGER.warn("医生ID不存在 doctorId:{}", baseInfoVO.getUserId());
            throw new BusinessException(ExceptionCodes.USER_NOT_EXIST);
        }

        if (StringUtils.isNotBlank(baseInfoVO.getName())) {
            doctor.setName(baseInfoVO.getName());
        }
        if (StringUtils.isNotBlank(baseInfoVO.getPhone())) {
            doctor.setPhone(baseInfoVO.getPhone());
        }
        if (baseInfoVO.getTitleId() != null) {
            doctor.setTitleId(baseInfoVO.getTitleId());
        }
        if (StringUtils.isNotBlank(baseInfoVO.getHeadUrl())) {
            // 更新用户头像
            doctor.setHeadUrl(baseInfoVO.getHeadUrl());
        }

        // 更新电子签名签章照
        //String path = this.generationSealImg(doctor.getId(), doctor.getName());
        //path = path.replaceAll(this.fileBasePrefix, "");
        //doctor.setSealImage(path);

        if (baseInfoVO.getHopitalId() != null) {
            // 查询医院
            Hospital hospital = this.hospitalRepository.get(baseInfoVO.getHopitalId());
            if (hospital == null) {
                throw new BusinessException(ExceptionCodes.PARAM_ERROR, "医院ID不存在");
            }
            doctor.setHospitalId(hospital.getId());
            doctor.sethospitalName(hospital.getName());
        }

        // 身份证
        String idCardNum = baseInfoVO.getIdCardNum();
        if (StringUtils.isNotBlank(idCardNum)
            || (baseInfoVO.getIdCardNum() != null && baseInfoVO.getIdCardUrls().size() > 0)) {
            if (idCardNum.length() == 18 && idCardNum.toUpperCase().endsWith("*")) {
                idCardNum = idCardNum.substring(0, 17) + "X";
            }
            // 校验身份证
            if (!IdcardUtil.isValidCard(idCardNum)) {
                throw new BusinessException(ExceptionCodes.PARAM_ERROR_ID_CARD_NUM);
            }
            List<Licence> licences = licenceDao.getLicenceByTypeAndNumber(DOCTOR_LICENCE_TYPE_IDCARD, idCardNum);
            if (licences.size() > 1) {
                throw new BusinessException(ExceptionCodes.DOCTOR_RECORD_INFO_ID_NUMBER_IS_EXISTS);
            }
            if (licences.size() == 1) {
                if (!baseInfoVO.getUserId().equals(licences.get(0).getDoctorId())
                    && idCardNum.equals(licences.get(0).getNumber())) {
                    throw new BusinessException(ExceptionCodes.DOCTOR_RECORD_INFO_ID_NUMBER_IS_EXISTS);
                }
            }
            this.updateDoctorLicence(baseInfoVO.getUserId(), Licence.DOCTOR_LICENCE_TYPE_IDCARD, idCardNum,
                    baseInfoVO.getIdCardUrls(), operator);
        }

        // 执业证
        if (StringUtils.isNotBlank(baseInfoVO.getPracNum()) || (baseInfoVO.getPracUrls() != null && baseInfoVO.getPracUrls().size() > 0)) {
            this.updateDoctorLicence(baseInfoVO.getUserId(), Licence.DOCTOR_LICENCE_TYPE_MEDICAL, baseInfoVO.getPracNum(),
                    baseInfoVO.getPracUrls(), operator);
        }

        // 资格证
        if (StringUtils.isNotBlank(baseInfoVO.getCertNum()) || (baseInfoVO.getCertUrls() != null && baseInfoVO.getCertUrls().size() > 0)) {
            this.updateDoctorLicence(baseInfoVO.getUserId(), Licence.DOCTOR_LICENCE_TYPE_QUALIFICATION_CERTIFICATE, baseInfoVO.getCertNum(),
                    baseInfoVO.getCertUrls(), operator);
        }

        doctor.setChangedAt(new Date());
        doctor.setChangedBy(operator);
        this.doctorRepository.update(doctor);

        return this.getUserCode(doctor.getId(), RecordUserInfo.USER_TYPE_DR);
    }

    private void updateDoctorLicence(Long doctorId, Integer type, String number, List<String> urls, String operator) {
        List<Licence> licences = this.licenceRepository.findByDoctorIdAndType(doctorId, type);
        Licence licence;
        boolean create = false;
        if (licences != null && !licences.isEmpty()) {
            licence = licences.get(0);
        } else {
            licence = new Licence();
            licence.setDoctorId(doctorId);
            licence.setType(type);
            licence.setCreatedAt(new Date());
            licence.setCreatedBy("system");
            create = true;
        }

        if (StringUtils.isNotBlank(number)) {
            licence.setNumber(number);
        }
        if (urls != null && urls.size() > 0) {
            licence.setUrl(String.join(",", urls));
        }
        licence.setChangedAt(new Date());
        licence.setChangedBy(operator);
        if (create) {
            this.licenceRepository.save(licence);
        } else {
            this.licenceRepository.update(licence);
        }
    }

    private String generationSealImg(Long doctorId, String doctorName) throws BusinessException {
        String filepath = this.sealPathPre + "dr/" + doctorId + ".png";
        boolean result = false;
        try {
            result = SealImageUtil.graphicsGeneration(ConfigUtil.getString("ehp.hospital.name") + TITLE_SUFFIX, "医生：" + doctorName,
                    filepath);
        } catch (IOException e) {
            LOGGER.error("生成签章图片异常 doctorId:{}", doctorId, e);
            throw new BusinessException(ExceptionCodes.FAILED, "生成签章图片异常");
        }

        if (!result) {
            LOGGER.warn("签章文件生成失败 doctorId:{}", doctorId);
            throw new BusinessException(ExceptionCodes.FAILED, "签章文件生成失败");
        }
        return filepath;
    }
}
